#pragma once;

#include "glm/glm.hpp"

// TODO, would make compilation faster if these were forward decls, but they are dependant
// on getting the mDevice from renderer,... which is dependant on the definition
// of an abstract renderer ofc... so.. need a re-architecturing to achieve that.
#include "../include/dexgel/texture.hpp"
#include "../include/dexgel/mesh.hpp"
#include "../include/dexgel/vertex_types.hpp"

namespace dexgel
{

	typedef enum _DEXGELLIGHTTYPE {
		LIGHT_POINT          = 1,
		LIGHT_SPOT           = 2,
		LIGHT_DIRECTIONAL    = 3,
		LIGHT_FORCE_DWORD    = 0x7fffffff, /* force 32-bit size enum */
	} DEXGELLIGHTTYPE;


	class Rendrer
	{
	public:


		Rendrer() { /* do nothing */ }
		virtual void begin() = 0; // Begins a scene
		virtual void end() = 0; // Ends a scene
		virtual bool render(Mesh *m) = 0;
		virtual bool render(SVertex *vertList, int numTris) = 0;
		virtual bool render(LitVertex *vertList, int numTris) = 0;
		virtual bool render(VertexUV *vertList, int numTris) = 0;
		virtual bool renderLine( SVertex *gVertPool, int numVerts ) = 0;
		virtual bool render(SVertex *vertList, int numVerts, unsigned short *indexList, int numIndices) = 0;
		virtual bool clearColor(int color, float zDepth = 1.0f) = 0;
		virtual void setViewMatrix(const glm::vec3 &eye, const glm::vec3 &target) = 0;
		virtual void setViewMatrix(float* matrix) = 0;
		virtual void setProjMatrix(float fov, float aspectRatio, float nearClip, float farClip) = 0;
		virtual void setProjOrtho( float* projectionMtx ) = 0;
		virtual void SetTransform( float* matWorld ) = 0;

		// Lighting parameter functions
		virtual void setLightType(int which, DEXGELLIGHTTYPE type) = 0;
		virtual void setLightPos(int which, const glm::vec3 &pos) = 0;
		virtual void setLightDir(int which, const glm::vec3 &dir) = 0;
		virtual void setLightColor(int which, int diffuse, int specular, int ambient) = 0;
		virtual void setLightAttenuation(int which, float constant, float linear, float quad ) = 0;
		virtual void setLightRange(int which, float r) = 0;
		virtual void setLightRadius(int which, float innerCone, float outerCone) = 0;
		virtual void setLightActive(int which, bool onOrOff) = 0;
		virtual void enableLighting() = 0;
		virtual void disableLighting() = 0;

		virtual Texture* loadTexture( const std::string filename ) = 0;
		virtual Mesh*	 createMesh( SVertex* verts, int numVerts ) = 0;
		virtual Mesh*	 createMesh( LitVertex* verts, int numVerts ) = 0;

		virtual ~Rendrer() { /* do nothing */ }; 


	private:

		Rendrer(const Rendrer &obj) {}
		Rendrer& operator =(Rendrer &obj) { return *this; }

	protected:
		glm::mat4 mWorldView;
		glm::mat4 mProjection;
		glm::mat4 mWorld;
		

	};

	// Here we define our global 3D object
	extern Rendrer *g3D;
}
